x86/nmi: correctly check MSB of P6 performance counter MSR in watchdog
authorIgor Druzhinin <igor.druzhinin@citrix.com>
Mon, 18 Mar 2019 16:04:30 +0000 (17:04 +0100)
committerJan Beulich <jbeulich@suse.com>
Mon, 18 Mar 2019 16:04:30 +0000 (17:04 +0100)
commit03afae62a7704d38f3c4d4d7ec66f510a86b1489
treedf7d28f800b0066fb2040e21668c5464b201b5d3
parentaea41c3d1080fb13536ef6501e0a004bc7e653ca
x86/nmi: correctly check MSB of P6 performance counter MSR in watchdog

The logic currently tries to work out if a recent overflow (that indicates
that NMI comes from the watchdog) happened by checking MSB of performance
counter MSR that is initially sign extended from a negative value
that we program it to. A possibly incorrect assumption here is that
MSB is always bit 32 while on modern hardware it's usually 47 and
the actual bit-width is reported through CPUID. Checking bit 32 for
overflows is usually fine since we never program it to anything
exceeding 32-bits and NMI is handled shortly after overflow occurs.

A problematic scenario that we saw occurs on systems where SMIs taking
significant time are possible. In that case, NMI handling is deferred to
the point firmware exits SMI which might take enough time for the counter
to go through bit 32 and set it to 1 again. So the logic described above
will misread it and report an unknown NMI erroneously.

Fortunately, we can use the actual MSB, which is usually higher than the
currently hardcoded 32, and treat this case correctly at least on modern
hardware.

Signed-off-by: Igor Druzhinin <igor.druzhinin@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
master commit: 0452d02b6e7849537914dd30cbfc8eb27cdad2ce
master date: 2019-02-28 13:44:40 +0000
xen/arch/x86/nmi.c